From: Joseph Marrero Corchado Date: Mon, 13 Apr 2026 02:20:38 +0000 (-0400) Subject: kargs: Fix crash on quoted values in /proc/cmdline X-Git-Tag: archive/raspbian/2026.2-1+rpi1^2~9^2^2~2^2 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=4f104a3f94e911e810e30d52a620721a68ba5c5c;p=ostree.git kargs: Fix crash on quoted values in /proc/cmdline Bootloaders like GRUB may reformat quoted kernel arguments, producing entries like "testparam=value with spaces" in /proc/cmdline. The proc-cmdline parser was still using a naive space split (pre-dating the quote-aware splitter added in abc7d5b9), so these tokens got broken apart and hit a g_assert_false() abort downstream. Use the quote-aware splitter for /proc/cmdline too, and downgrade the unterminated-quote assert to g_debug() since we can't control what bootloaders emit. Reported by Arch Linux maintainers building ostree 2026.1. Closes: https://github.com/ostreedev/ostree/issues/3582 Assisted-by: OpenCode (Claude Opus 4.6) Signed-off-by: Joseph Marrero Corchado --- diff --git a/src/libostree/ostree-kernel-args.c b/src/libostree/ostree-kernel-args.c index 056b3fa9..3b33f161 100644 --- a/src/libostree/ostree-kernel-args.c +++ b/src/libostree/ostree-kernel-args.c @@ -188,13 +188,14 @@ split_kernel_args (const char *str) } } - // Add the last slice - if (!quoted) - g_ptr_array_add (strv, g_strndup (start, str + len - start)); - else + // Add the last slice if non-empty. If there's an unterminated quote + // (e.g. from bootloader-reformatted /proc/cmdline), treat the + // remainder as a single token rather than aborting. + if (str + len > start) { - g_debug ("Missing terminating quote in '%s'.\n", str); - g_assert_false (quoted); + if (quoted) + g_debug ("Missing terminating quote in '%s', treating remainder as single token.\n", str); + g_ptr_array_add (strv, g_strndup (start, str + len - start)); } g_ptr_array_add (strv, NULL); @@ -681,7 +682,7 @@ ostree_kernel_args_append_proc_cmdline (OstreeKernelArgs *kargs, GCancellable *c g_strchomp (proc_cmdline); - proc_cmdline_args = g_strsplit (proc_cmdline, " ", -1); + proc_cmdline_args = split_kernel_args (proc_cmdline); ostree_kernel_args_append_argv_filtered (kargs, proc_cmdline_args, filtered_prefixes); return TRUE; diff --git a/tests/kolainst/destructive/kargs-proc-cmdline-quoted.sh b/tests/kolainst/destructive/kargs-proc-cmdline-quoted.sh new file mode 100755 index 00000000..32d8d1f9 --- /dev/null +++ b/tests/kolainst/destructive/kargs-proc-cmdline-quoted.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# Verify ostree handles quoted kernel args with spaces in /proc/cmdline. +# +# Regression test for a bug introduced in abc7d5b9 where +# ostree_kernel_args_append_proc_cmdline() used a naive g_strsplit(" ") +# to tokenize /proc/cmdline, then passed the fragments to +# ostree_kernel_args_append() which calls the quote-aware +# split_kernel_args(). Fragments with unterminated quotes caused a +# g_assert_false(quoted) abort. +# +# The bootloader (GRUB) may reformat quoted kargs -- e.g. what +# rpm-ostree stores as testparam="value with spaces" can appear in +# /proc/cmdline as "testparam=value with spaces" (quotes wrapping +# the entire token). The parser must handle both forms. + +set -xeuo pipefail + +. ${KOLA_EXT_DATA}/libinsttest.sh + +case "${AUTOPKGTEST_REBOOT_MARK:-}" in +"") + # Append a quoted karg containing spaces + rpm-ostree kargs --append='testparam="value with spaces"' + /tmp/autopkgtest-reboot "verify" + ;; +"verify") + # The karg should be present in /proc/cmdline (possibly reformatted + # by the bootloader, e.g. "testparam=value with spaces") + assert_file_has_content /proc/cmdline testparam + + # These commands read /proc/cmdline and previously crashed with: + # g_assert_false(quoted) in split_kernel_args() + ostree admin instutil set-kargs --import-proc-cmdline + echo "ok import-proc-cmdline with quoted kargs" + + host_commit=$(ostree admin status | sed -n 's/^.* \(.*\)\.0$/\1/p' | head -1) + ostree admin deploy --karg-proc-cmdline "${host_commit}" + echo "ok deploy --karg-proc-cmdline with quoted kargs" + ;; +*) + fatal "Unexpected AUTOPKGTEST_REBOOT_MARK=${AUTOPKGTEST_REBOOT_MARK}" + ;; +esac diff --git a/tests/test-kargs.c b/tests/test-kargs.c index 90f11e5f..3573657e 100644 --- a/tests/test-kargs.c +++ b/tests/test-kargs.c @@ -278,6 +278,55 @@ test_kargs_append (void) g_assert_cmpint (7, ==, g_strv_length (kargs_list)); } +/* Regression test: parsing a /proc/cmdline-style string containing quoted + * kernel args with spaces must not crash. Commit abc7d5b9 added a + * quote-aware splitter (split_kernel_args) but ostree_kernel_args_append_proc_cmdline + * still used a naive g_strsplit(" ") that broke quoted tokens apart, causing a + * g_assert_false(quoted) abort. + * + * Bootloaders may reformat quotes -- e.g. GRUB turns testparam="value with spaces" + * into "testparam=value with spaces" in /proc/cmdline. Both forms must be handled. + */ +static void +test_kargs_quoted_cmdline (void) +{ + /* Test 1: Standard quoted value (as stored by rpm-ostree) */ + { + __attribute__ ((cleanup (ostree_kernel_args_cleanup))) OstreeKernelArgs *karg + = ostree_kernel_args_new (); + ostree_kernel_args_parse_append (karg, + "root=UUID=abc quiet testparam=\"value with spaces\" rw"); + g_assert (check_string_existance (karg, "root=UUID=abc")); + g_assert (check_string_existance (karg, "quiet")); + g_assert (check_string_existance (karg, "testparam=\"value with spaces\"")); + g_assert (check_string_existance (karg, "rw")); + } + + /* Test 2: GRUB-reformatted quoting (quotes wrapping entire token) + * /proc/cmdline may show: "testparam=value with spaces" */ + { + __attribute__ ((cleanup (ostree_kernel_args_cleanup))) OstreeKernelArgs *karg + = ostree_kernel_args_new (); + ostree_kernel_args_parse_append (karg, + "root=UUID=abc quiet \"testparam=value with spaces\" rw"); + g_assert (check_string_existance (karg, "root=UUID=abc")); + g_assert (check_string_existance (karg, "quiet")); + g_assert (check_string_existance (karg, "\"testparam=value with spaces\"")); + g_assert (check_string_existance (karg, "rw")); + } + + /* Test 3: Multiple quoted args */ + { + __attribute__ ((cleanup (ostree_kernel_args_cleanup))) OstreeKernelArgs *karg + = ostree_kernel_args_new (); + ostree_kernel_args_parse_append (karg, "foo=\"1 2\" bar=\"3 4\""); + g_assert (check_string_existance (karg, "foo=\"1 2\"")); + g_assert (check_string_existance (karg, "bar=\"3 4\"")); + g_auto (GStrv) kargs_list = ostree_kernel_args_to_strv (karg); + g_assert_cmpint (2, ==, g_strv_length (kargs_list)); + } +} + int main (int argc, char *argv[]) { @@ -286,5 +335,6 @@ main (int argc, char *argv[]) g_test_add_func ("/kargs/kargs_append", test_kargs_append); g_test_add_func ("/kargs/kargs_delete", test_kargs_delete); g_test_add_func ("/kargs/kargs_replace", test_kargs_replace); + g_test_add_func ("/kargs/kargs_quoted_cmdline", test_kargs_quoted_cmdline); return g_test_run (); }